package com.arcpan.Controller;

import com.arcpan.Constant.BaseConstant;
import com.arcpan.Entity.Dto.SessionWebUserDto;
import com.arcpan.Entity.Dto.UserSpaceDto;
import com.arcpan.Entity.UserInfo;
import com.arcpan.Exception.BaseException;
import com.arcpan.Mapper.UserInfoMapper;
import com.arcpan.Result.Result;
import com.arcpan.Service.EmailCodeService;
import com.arcpan.Service.UserInfoService;
import com.arcpan.Util.CreateImageCode;
import com.arcpan.Util.StringTools;
import com.arcpan.annotation.GlobalInterceptor;
import com.arcpan.annotation.VerifyParams;
import com.arcpan.config.AppConfig;
import com.arcpan.enums.VerifyRegexEnum;
import com.sun.deploy.net.HttpResponse;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.net.URLEncoder;
import java.text.FieldPosition;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

@RestController
@RequestMapping("/")
public class AccountController {
    @Resource
    private UserInfoService userInfoService;
    @Resource
    private EmailCodeService emailCodeService;
    @Resource
    private AppConfig appConfig;
    private static final String CONTENT_TYPE = "Content-Type";
    private static final String CONTENT_TYPE_VALUE = "application/json;charset=UTF-8";
    @Resource
    private UserInfoMapper userInfoMapper;


    @RequestMapping("/checkCode")
    @GlobalInterceptor(checkParam = true, checkLogin = false)
    public void checkCode(HttpServletResponse response, HttpSession session, Integer type) throws IOException {
        CreateImageCode vcode = new CreateImageCode(130, 38, 4);
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        //生效时间
        response.setDateHeader("Expires", 0);
        response.setContentType("image/jpeg");
        String code = vcode.getCode();

        if (type == null || type == 0) {
            //登录注册
            session.setAttribute(BaseConstant.CHECK_CODE_KEY, code);
            System.out.println(code + "注册");
        } else {
            session.setAttribute(BaseConstant.CHECK_CODE_KEY_EMAIL, code);
            System.out.println(code + "邮箱");

        }
        System.out.println((String) session.getAttribute(BaseConstant.CHECK_CODE_KEY_EMAIL));

        vcode.write(response.getOutputStream());
    }

    @RequestMapping("/sendEmailCode")
    @GlobalInterceptor(checkParam = true, checkLogin = false)
    public Result sendEmailCode(HttpSession httpSession, @VerifyParams(required = true, regex = VerifyRegexEnum.EMAIL, max = 150) String email, @VerifyParams(required = true) String checkCode, @VerifyParams(required = true) Integer type) {
        try {
            if (!checkCode.equalsIgnoreCase((String) httpSession.getAttribute(BaseConstant.CHECK_CODE_KEY_EMAIL))) {
                throw new BaseException("验证码错误");
            }
            emailCodeService.sendEmailCode(email, type);
            return Result.success();
        } finally {
            httpSession.removeAttribute(BaseConstant.CHECK_CODE_KEY_EMAIL);
        }

    }

    @RequestMapping("/register")
    @GlobalInterceptor(checkParam = true, checkLogin = false)
    public Result register(HttpSession httpSession, @VerifyParams(required = true, regex = VerifyRegexEnum.EMAIL, max = 150) String email, @VerifyParams(required = true) String nickName, @VerifyParams(required = true, regex = VerifyRegexEnum.PASSWORD, min = 8, max = 18) String password, @VerifyParams(required = true) String checkCode, @VerifyParams(required = true) Integer emailCode) {
        try {
            if (!checkCode.equalsIgnoreCase((String) httpSession.getAttribute(BaseConstant.CHECK_CODE_KEY))) {
                throw new BaseException("验证码错误");
            }
            userInfoService.register(email, nickName, password, emailCode);
            return Result.success();
        } finally {
            httpSession.removeAttribute(BaseConstant.CHECK_CODE_KEY);
        }

    }

    @RequestMapping("/login")
    @GlobalInterceptor(checkParam = true, checkLogin = false)
    public Result login(HttpSession httpSession, @VerifyParams(required = true, regex = VerifyRegexEnum.EMAIL, max = 150) String email, @VerifyParams(required = true) String password, @VerifyParams(required = true) String checkCode) {
        System.out.println(email);
        System.out.println(password + checkCode + "-");
        try {

            if (!checkCode.equalsIgnoreCase((String) httpSession.getAttribute(BaseConstant.CHECK_CODE_KEY))) {
                throw new BaseException("验证码错误");
            }
            SessionWebUserDto sessionWebUserDto = userInfoService.login(email, password);
            httpSession.setAttribute(BaseConstant.SESSION_KEY, sessionWebUserDto);
            return Result.success(sessionWebUserDto);

        } finally {
            httpSession.removeAttribute(BaseConstant.CHECK_CODE_KEY);

        }

    }

    @RequestMapping("/resetPwd")
    @GlobalInterceptor(checkParam = true, checkLogin = false)
    public Result resetPwd(HttpSession httpSession, @VerifyParams(required = true, regex = VerifyRegexEnum.EMAIL, max = 150) String email, @VerifyParams(required = true, regex = VerifyRegexEnum.PASSWORD, min = 8, max = 18) String password, @VerifyParams(required = true) String checkCode, @VerifyParams(required = true) Integer emailCode) {
        try {
            if (!checkCode.equalsIgnoreCase((String) httpSession.getAttribute(BaseConstant.CHECK_CODE_KEY))) {
                throw new BaseException("验证码错误");
            }
            userInfoService.resetPwd(email, password, emailCode);

            return Result.success();
        } finally {
            httpSession.removeAttribute(BaseConstant.CHECK_CODE_KEY);
        }

    }

    @RequestMapping("/getAvatar/{userId}")
    public void getAvatar(HttpServletResponse httpServletResponse, HttpSession httpSession, @VerifyParams(required = true) @PathVariable("userId") String userId) {
        String projectFolder = appConfig.getProjectFolder();
        String avatarFolderName = projectFolder + BaseConstant.FILE_FOLDER_FILE + BaseConstant.FILE_FOLDER_AVATAR_NAME;
        File folder = new File(avatarFolderName);
        if (!folder.exists()) {
            folder.mkdirs();
        }

        String avatarPath = avatarFolderName + userId + BaseConstant.AVATAR_SUFFIX;
        File file = new File(avatarPath);
        if (!file.exists()) {
            if (!new File(avatarFolderName + BaseConstant.AVATAR_DEFUALT).exists()) {

                printNoDefaultImage(httpServletResponse);
            }
            avatarPath = avatarFolderName + BaseConstant.AVATAR_DEFUALT;
        }
        httpServletResponse.setContentType("image/jpg");
        readFile(httpServletResponse, avatarPath);

    }

    @RequestMapping("/getUserInfo")
    @GlobalInterceptor(checkParam = false, checkLogin = true)
    public Result getUserInfo(HttpSession httpSession) {
        SessionWebUserDto sessionWebUserDto = (SessionWebUserDto) httpSession.getAttribute(BaseConstant.SESSION_KEY);
        return Result.success(sessionWebUserDto);
    }

    @RequestMapping("/getUseSpace")
    @GlobalInterceptor(checkParam = false, checkLogin = true)
    public Result getUseSpace(HttpSession httpSession) {
        SessionWebUserDto sessionWebUserDto = (SessionWebUserDto) httpSession.getAttribute(BaseConstant.SESSION_KEY);
        UserSpaceDto userSpaceDto = userInfoService.getspace(sessionWebUserDto.getUserId());
        return Result.success(userSpaceDto);
    }

    @RequestMapping("/logout")
    public Result logout(HttpSession httpSession) {
        httpSession.removeAttribute(BaseConstant.SESSION_KEY);
        return Result.success();
    }

    @RequestMapping("/qqlogin")
    @GlobalInterceptor(checkParam = true, checkLogin = false)
    public Result qqlogin(HttpSession httpSession, String callbackUrl) throws UnsupportedEncodingException {
        System.out.println(callbackUrl+"cal");
       String state = StringTools.getRandomNumber(BaseConstant.LENGTH_30);
        if (!StringTools.isEmpty(callbackUrl)) {
            httpSession.setAttribute(state, callbackUrl);
        }
        String url=String.format(appConfig.getQqUrlAuthorization(),appConfig.getQqAppId(), URLEncoder.encode(appConfig.getQqUrlRedirect(),"utf-8"),state);



        return Result.success(url);
    }
    @RequestMapping("/qqlogin/callback")
    @GlobalInterceptor(checkParam = true,checkLogin = false)
    public Result getlogincallback(HttpSession httpSession,@VerifyParams(required = true) String code,@VerifyParams(required = true) String state){
        SessionWebUserDto sessionWebUserDto=userInfoService.qqlogin(code);
       httpSession.setAttribute(BaseConstant.SESSION_KEY,sessionWebUserDto);
        Map<String,Object> map=new HashMap<>();
        map.put("callbackUrl",httpSession.getAttribute(state));
        map.put("userInfo",sessionWebUserDto);
return Result.success(map);
    }
@RequestMapping("/updateTotalSpace")
@GlobalInterceptor(checkLogin = true)
public Result updateTotalSpace(HttpSession httpSession,Long totalSpace){
        SessionWebUserDto sessionWebUserDto= (SessionWebUserDto) httpSession.getAttribute(BaseConstant.SESSION_KEY);
        String userId=sessionWebUserDto.getUserId();
        UserInfo userInfo=userInfoMapper.selectByUserId(userId);
        userInfo.setTotalSpace(totalSpace);
        userInfoMapper.updateByUserId(userInfo,userId);
        return Result.success();
}
    @RequestMapping("/updatePassword")
    @GlobalInterceptor(checkParam = false, checkLogin = true)
    public Result updatePassword(HttpSession httpSession, String password) {
        SessionWebUserDto sessionWebUserDto = (SessionWebUserDto) httpSession.getAttribute(BaseConstant.SESSION_KEY);
        UserInfo userInfo = userInfoMapper.selectByUserId(sessionWebUserDto.getUserId());
        userInfo.setPassword(DigestUtils.md5Hex(password));
        userInfoMapper.updateByUserId(userInfo, userInfo.getUserId());
        return Result.success();
    }

    @RequestMapping("/updateUserAvatar")
    @GlobalInterceptor(checkParam = true, checkLogin = true)
    public Result updateUserAvatar(HttpSession httpSession, MultipartFile avatar) {
        SessionWebUserDto sessionWebUserDto = (SessionWebUserDto) httpSession.getAttribute(BaseConstant.SESSION_KEY);
        String projectFolder = appConfig.getProjectFolder();
        String avatarFolderName = projectFolder + BaseConstant.FILE_FOLDER_FILE + BaseConstant.FILE_FOLDER_AVATAR_NAME;
        File file1 = new File(avatarFolderName);
        if (!file1.exists()) {
            file1.mkdirs();
        }
        String targetFile = projectFolder + BaseConstant.FILE_FOLDER_FILE + BaseConstant.FILE_FOLDER_AVATAR_NAME + sessionWebUserDto.getUserId() + BaseConstant.AVATAR_SUFFIX;
        try {
            avatar.transferTo(new File(targetFile));
        } catch (Exception e) {
            throw new BaseException(e.getMessage());
        }

        UserInfo userInfo = userInfoMapper.selectByUserId(sessionWebUserDto.getUserId());
        userInfo.setQqAvatar("");
        userInfoMapper.updateByUserId(userInfo, userInfo.getUserId());
        sessionWebUserDto.setAvatar(null);
        httpSession.setAttribute(BaseConstant.SESSION_KEY, sessionWebUserDto);
        return Result.success();


    }

    private void printNoDefaultImage(HttpServletResponse response) {
        response.setHeader(CONTENT_TYPE, CONTENT_TYPE_VALUE);
        response.setStatus(HttpStatus.OK.value());
        PrintWriter writer = null;
        try {
            writer = response.getWriter();
            writer.print("请在头像目录下放置默认头像default_avatar.jpg");
            writer.close();
        } catch (Exception e) {

        } finally {
            writer.close();
        }
    }

    protected void readFile(HttpServletResponse response, String filePath) {
        if (!StringTools.pathIsOk(filePath)) {
            return;
        }
        OutputStream out = null;
        FileInputStream in = null;
        try {
            File file = new File(filePath);
            if (!file.exists()) {
                return;
            }
            in = new FileInputStream(file);
            byte[] byteData = new byte[1024];
            out = response.getOutputStream();
            int len = 0;
            while ((len = in.read(byteData)) != -1) {
                out.write(byteData, 0, len);
            }
            out.flush();
        } catch (Exception e) {

        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {

                }
            }
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {

                }
            }
        }
    }
}
